#ifndef __APP_IR_H_
#define __APP_IR_H_

#include <drv/spiflash.h>
#include "ir_base.h"

/******************************************************************************
                               红外指令
******************************************************************************/
typedef enum {
    IR_DEV_AIR_COND = 5,
    IR_DEV_FAN_DEVICE,
} ir_device_type_t;

/**
 * @brief 初始化遥控器参数，需要在其他所有初始化完成后再调用该函数 
 */
void remote_data_init();

/**
 * @brief 匹配空调遥控器
 * @return 0: OK    -1:error
 */
int match_remote_process(void);


/**
 * @brief 切换空调遥控器
 * @return 0: OK    -1:error
 */
int event_next_air_remote();

/**
 * @brief 打开空调
 * @return none
 */

int event_air_power_on();
 
/**
 * @brief 关闭空调
 * @return none
 */
int event_air_power_off();

/**
 * @brief 制冷模式
 * @return none
 */
int event_air_mode_cool();

/**
 * @brief 加热模式
 * @return none
 */
int event_air_mode_hot();

/**
 * @brief 自动模式
 * @return none
 */
int event_air_mode_auto();

/**
 * @brief 送风模式
 * @return none
 */
int event_air_mode_wind();

/**
 * @brief 除湿模式
 * @return none
 */
int event_air_mode_wetted();

/**
 * @brief 空调温度设置
 * @param[in] {value}    温度[16-30]
 * @return 0: OK    1: out of range  -1: Can't adjust
 */
int event_air_temperature_set(unsigned char value);

/**
 * @brief 调高温度
 * @return 0: OK    1: max  -1: Can't adjust
 */
int event_air_temperature_increase();

/**
 * @brief 调低温度
 * @return 0: OK    1: min  -1: Can't adjust
 */
int event_air_temperature_reduce();

/**
 * @brief 自动风量
 * @return none
 */
int event_air_wind_speed_auto();

/**
 * @brief 最小风量
 * @return none
 */
int event_air_wind_speed_min();

/**
 * @brief 中等风量
 * @return none
 */
int event_air_wind_speed_mid();

/**
 * @brief 最大风量
 * @return none
 */
int event_air_wind_speed_max();

/**
 * @brief 上下扫风
 * @return none
 */
int event_air_mode_direction();

/**
 * @brief 停止扫风
 * @return none
 */
int event_air_mode_stop_direction();

int asr_ir_deal(int item);
int asr_set_temparature(unsigned char temp);

/* item */
typedef enum
{
    ASR_XIAO_ZHI = 0,
    ASR_YU_YIN_DAO_HANG,

    ASR_PI_PEI_KONG_TIAO,
    ASR_PI_PEI_DIAN_FENG_SAN,
    ASR_PI_PEI_FENG_SAN,
    ASR_XUE_XI_FENG_SAN,

    ASR_DA_KAI_KONG_TIAO,
    ASR_GUAN_BI_KONG_TIAO,
    ASR_ZHI_LENG_MO_SHI,
    ASR_ZHI_RE_MO_SHI,
    ASR_JIA_RE_MO_SHI,
    ASR_CHOU_SHI_MO_SHI,
    ASR_HUAN_QI_MO_SHI,
    ASR_SONG_FENG_MO_SHI,
    ASR_TIAO_GAO_WEN_DU,
    ASR_SHENG_GAO_WEN_DU,
    ASR_TIAO_DI_WEN_DU,
    ASR_JIANG_DI_WEN_DU,
    ASR_16_DU,
    ASR_17_DU,
    ASR_18_DU,
    ASR_19_DU,
    ASR_20_DU,
    ASR_21_DU,
    ASR_22_DU,
    ASR_23_DU,
    ASR_24_DU,
    ASR_25_DU,
    ASR_26_DU,
    ASR_27_DU,
    ASR_28_DU,
    ASR_29_DU,
    ASR_30_DU,
    ASR_ZUI_DA_FENG_LIANG,
    ASR_ZUI_XIAO_FENG_LIANG,
    ASR_ZHONG_DENG_FENG_LIANG,
    ASR_ZI_DONG_FENG_LIANG,
    ASR_SHANG_XIA_BAI_FENG,
    ASR_TING_ZHI_BAI_FENG,

    ASR_DA_KAI_DIAN_FENG_SAN,
    ASR_GUAN_BI_DIAN_FENG_SAN,
    ASR_DA_KAI_FENG_SAN,
    ASR_GUAN_BI_FENG_SAN,
    ASR_YAO_TOU_GONG_NENG,
    ASR_KAI_SHI_YAO_TOU,
    ASR_TING_ZHI_YAO_TOU,
    ASR_SHANG_XIA_YAO_TOU,
    ASR_ZUO_YOU_YAO_TOU,
    ASR_BIAN_SU_GONG_NENG,
    ASR_TIAO_DA_FENG_SU,
    ASR_TIAO_XIAO_FENG_SU,
    ASR_DING_SHI_GONG_NENG,
    ASR_ZENG_JIA_DING_SHI,
    ASR_JIAN_XIAO_DING_SHI,
    ASR_JING_HUA_GONG_NENG,
    ASR_KAI_SHI_JING_HUA,
    ASR_TING_ZHI_JING_HUA,
    ASR_QIE_HUAN_MO_SHI,
    ASR_AI_MO_SHI,

    ASR_DA_KAI_YU_YIN,
    ASR_GUAN_BI_YU_YIN,

    
    ASR_VOL_UP,
    ASR_VOL_DOWN,
    
    ASR_QIE_HUAN_KONG_TIAO_MA_KU,

    ASR_RESPONSE_RESULT_INDEX,
} ASR_CMD_INDEX;

/******************************************************************************
                               空调红外接口
******************************************************************************/

typedef struct
{
    unsigned char key[20];
    unsigned char _flag;     
    unsigned short _num;     //返回根据传入的电平搜索到的遥控码总套数
    unsigned short _id;      //控码的id
    unsigned short _handle;  //遥控码的句柄
    unsigned short _len;     //返回第一套遥控码数据长度
    int _offset;             //遥控码在数据文件中的偏移量
    unsigned short _cur_num; //遥控码在数据文件中的偏移量

    unsigned short _one_id;     //第一套遥控码的id
    unsigned short _one_handle; //遥控码的句柄
    int _one_offset;            //遥控码在数据文件中的偏移量
    unsigned short _one_len;    //返回第一套遥控码数据长度
} REMOTE_PARA_T;

//#define REMOTE_FLASH_KEY_H 0xAA
//#define REMOTE_FLASH_KEY_L 0x55

typedef struct
{
    unsigned char key[20];
    unsigned char _power;          //开关 [0 开机， 1 关机]
    unsigned char _mode;           //模式 [0-4]对应制冷，制热，自动，送风，除湿
    unsigned char _temperature;    //温度 [16-30]
    unsigned char _wind_speed;     //风速 [0-3]对应自动，低，中，高
    unsigned char _wind_direction; //风向
    unsigned char _sync;
    unsigned short _frequency; //载波频率
} AIR_STA_T;

typedef struct
{
    unsigned char key[20];
    unsigned char _power;            
    unsigned char _speed;    
    unsigned char _swing;  
    unsigned char _timer; 
    unsigned char _mode;   
    unsigned short _frequency; //载波频率
} FAN_STA_T;

typedef struct
{
    unsigned char _power_flag;            
    unsigned char _speed_flag;    
    unsigned char _swing_flag;  
    unsigned char _timer_flag; 
    unsigned char _mode_flag; 
} FAN_INF_FLAG_T;
int get_remote_flag(unsigned char device_type);

/**
 * @brief 遥控器功能支持信息获取
 * @param[in] {AIR_STA_T air_ctr}    空调遥控器状态
 * @param[out] {wind_direct_flag}    风向支持
 * @return 0: OK    -1:获取数据失败 -2：不支持的模式 -3：不支持的温度 -4：不支持的风速 
 */
int remote_support_info(AIR_STA_T air_ctr, unsigned char *wind_direct_flag);

/**
 * @brief 空调开关控制
 * @param[in] {AIR_STA_T air_ctr}    空调遥控器状态
 * @return 0: OK    -1:没有可用的遥控器，需要先匹配  -2：获取遥控码失败
 */
int air_power_switch(AIR_STA_T air_ctr);

/**
 * @brief 空调风向控制
 * @param[in] {AIR_STA_T air_ctr}    空调遥控器状态
 * @param[in] {wind_direct_flag}     风向支持标志位
 * @return 0: OK    -1:没有可用的遥控器，需要先匹配  -2：获取遥控码失败
 */
int air_direct_ctrl(AIR_STA_T air_ctr, unsigned char wind_direct_flag);

/**
 * @brief 空调状态控制
 * @param[in] {AIR_STA_T air_ctr}    空调遥控器状态
 * @param[in] {wind_direct_flag}     风向支持标志位
 * @return 0: OK    -1:没有可用的遥控器，需要先匹配  -2：获取遥控码失败
 */
int air_control(AIR_STA_T air_ctr, unsigned char wind_direct_flag);

/**
 * @brief 学习空调红外码接口
 * @return 0: OK    -1:error
 */
int learn_pulse_start();

/**
 * @brief 在码库匹配遥控器接口
 * @param[in] {device_type}     设备号
 * @return 0: OK    -1:error
 */
int match_remote_start(unsigned char device_type);

/**
 * @brief 在码库读取遥控器数据/将遥控器参数写入flash
 * @param[in] {device_type}     设备号
 * @return 0: OK    -1:error
 */
int read_remote_code(unsigned char device_type);

/**
 * @brief 获取下一套遥控码
 * @param[in] {device_type}     设备号
 * @return 0: OK    -1:error
 */
int match_get_next_remote(unsigned char device_type);

/**
 * @brief 储存遥控器索引
 * @param[in] {data}            数据
 * @param[in] {len}             长度
 * @param[in] {device_type}     设备号
 * @return 0: OK    -1:error
 */
int save_remote_index_info(void *data, unsigned int len, unsigned char device_type);

/**
 * @brief 储存遥控器状态
 * @param[in] {data}            数据
 * @param[in] {len}             长度
 * @param[in] {device_type}     设备号
 * @return 0: OK    -1:error
 */
int save_user_sta_data(void *data, unsigned int len, unsigned char device_type);


/**
 * @brief 释放遥控器空间
 */
void free_remote_code();

/**********************************************************************
                        EXT FLASH Related API
**********************************************************************/
#define FLASH_READ_DATA             0x03
#define FLASH_FAST_READ_DATA        0x0B
#define FLASH_READ_STATUS           0x05
#define FLASH_READ_DEVICE_ID        0x90
#define FLASH_WRITE_ENABLE          0x06
#define FLASH_WRITE_DISABLE         0x04
#define FLASH_PAGE_PROGRAM          0x02
#define FLASH_RELEASE_POWER_DOWN    0x04
#define FLASH_SECTOR_ERASE          0x20

//16m GD25Q127C
#define SPI_FLASH_BLOCK_SIZE        0x10000
#define SPI_FLASH_SECTOR_SIZE       0x1000
#define SPI_FLASH_PAGE_SIZE         0x100
#define SPI_FLASH_BASEADDR          0x0
#define SPI_FLASH_END               0xFFFFFF
#define SPI_FLASH_SECTOR_NUM        0x1000
#define SPI_DEFAULT_CLK_RATE        1000000

//空调遥控索引
#define SPI_FLASH_REMOTE_ADDR                SPI_FLASH_SECTOR_NUM * 0
//空调遥控状态
#define SPI_FLASH_USER_AIR_DATA_ADDR         (SPI_FLASH_REMOTE_ADDR + SPI_FLASH_PAGE_SIZE)

#define SPI_FLASH_AIR_REMOTE_ADDR            (SPI_FLASH_SECTOR_NUM * 1)

//风扇遥控索引
#define SPI_FLASH_FAN_REMOTE_ADDR            SPI_FLASH_SECTOR_NUM * 1001
//风扇遥控状态
#define SPI_FLASH_USER_FAN_DATA_ADDR         (SPI_FLASH_FAN_REMOTE_ADDR + SPI_FLASH_PAGE_SIZE)

#define SPI_FLASH_POWER_ON_ADDR              SPI_FLASH_SECTOR_NUM * 1002
#define SPI_FLASH_POWER_OFF_ADDR             SPI_FLASH_SECTOR_NUM * 1003
#define SPI_FLASH_SHAKE_UP_DOWN_ADDR         SPI_FLASH_SECTOR_NUM * 1004
#define SPI_FLASH_SHAKE_LEFT_RIGHT_ADDR      SPI_FLASH_SECTOR_NUM * 1005
#define SPI_FLASH_SPEED_UP_ADDR              SPI_FLASH_SECTOR_NUM * 1006
#define SPI_FLASH_SPEED_DOWN_ADDR            SPI_FLASH_SECTOR_NUM * 1007
#define SPI_FLASH_TIMER_UP_ADDR              SPI_FLASH_SECTOR_NUM * 1008
#define SPI_FLASH_TIMER_DOWN_ADDR            SPI_FLASH_SECTOR_NUM * 1009
#define SPI_FLASH_PURIFY_ON_ADDR             SPI_FLASH_SECTOR_NUM * 1010
#define SPI_FLASH_PURIFY_OFF_ADDR            SPI_FLASH_SECTOR_NUM * 1011
#define SPI_FLASH_MODE_ADDR                  SPI_FLASH_SECTOR_NUM * 1012
#define SPI_FLASH_AI_MODE_ADDR               SPI_FLASH_SECTOR_NUM * 1013 

/**
 *  \struct     bindings_t
 *  \brief      low level communication interface
 */
typedef struct {
    int (*init)(void);
    void (*uninit)(void);
    int (*ioctl)(uint32_t value);
    int (*send)(const void *data, uint32_t size);
    int (*receive)(void *data, uint32_t size);
    int (*send_receive)(const void *data_out, void *data_in, uint32_t num);
} bindings_t;

/**
 *  \struct    flash_t
 *  \brief     ctrl block of flash instance
 */
typedef struct {
    bindings_t *binding;
} flash_t;

/*void app_spi_flash_init(void);
int app_spi_flash_read_buf(uint32_t addr, void *data, uint32_t size);
int app_spi_falsh_write_buf(unsigned int address, void *data, unsigned int size);
int app_spi_sector_earse(unsigned int address);
*/
// extern spiflash_handle_t spiflash_handler(void);
// #define app_spi_flash_init spiflash_init
// #define app_spi_flash_read_buf(addr, data, size) csi_spiflash_read(spiflash_handler(), addr, data, size)
// #define app_spi_falsh_write_buf(addr, data, size) csi_spiflash_program(spiflash_handler(), addr, data, size)

#endif